/* Copyright (c) 2012 Michele Roohani, Frank Harper, Pierre Gros, Pierre LEVY
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.aocfrance.app.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.aocfrance.app.Constants;
import com.aocfrance.app.model.Producteur;

public abstract class ProducteurService {
	private static final String JSONURL = "http://srv1.winememento.com:8000";
	private static final String PRODAPI = "/api/v1/producteur/";
	
	private static Map<Integer, Producteur> producteurs;

    public static Producteur loadProducteur(Integer id)
    {
        return getProducteurInThread( id );
    }

    public static List<Producteur> loadProducteursCommune(String communeId)
    {
        String url = JSONURL+PRODAPI+"?format=json&commune="+communeId;
        return getProducteursListInThread(url);
    }

    public static List<Producteur> loadProducteursAOC(String aocId )
    {
        String url = JSONURL+PRODAPI+"?format=json&&aoc="+aocId;
        return getProducteursListInThread(url);
    }
    
    public static boolean vote(String resource_uri, double rating) {
    	HttpClient client = new DefaultHttpClient();
		HttpResponse response;

		String URL = "http://srv1.winememento.com:8000/api/v1/avisproducteur/";


		HttpPost post = new HttpPost(URL);
		try {
			StringEntity se = new StringEntity("{\"avis\": \"Via Mobile\", \"producteur\": \""+resource_uri+"\", \"rating\": "+rating+"}");
			//se.setContentType("application/json;charset=UTF-8");
			se.setContentType("application/json");
			post.setEntity(se);
			response = client.execute(post); 
		} catch (Exception e) {
			return false;
		}

        /*Checking response */
        if(response!=null){
        	StatusLine statusLine = response.getStatusLine();
			int statusCode = statusLine.getStatusCode();
			return (statusCode==201);
        }
        return false;

    }
	

	private static Producteur getProducteurInThread(Integer id) {
		if(producteurs != null && producteurs.containsKey(id))
			return producteurs.get(id);
		String url = JSONURL+PRODAPI+id+"/?format=json";
		JSONObject json = getJSonStringForUrl(url);
		if(json==null)
			return null;
		try{
				int _id = json.getInt("id");
				double rating = 0;
				try {
					rating = json.getDouble("rating");
				} catch (JSONException e) {
					rating = 0;
				}
				
				Producteur p = new Producteur(
						_id, 
						json.getString("nom"), 
						json.getString("adresse"), 
						json.getString("presentation"), 
						rating, 
						json.getString("photo"), 
						json.getString("aoc"), 
						json.getString("commune"), 
						json.getString("resource_uri"));

				return p;
		}catch(JSONException e)        {
			Log.e("log_tag", "Error parsing data "+e.toString());
		}
		return null;
	}
	
	private static List<Producteur> getProducteursListInThread(String url) {
		List<Producteur> producteurList = new ArrayList<Producteur>();
		
		//String url = JSONURL+PRODAPI+"?format=json"+"&commune="+communeId;
		boolean fetchAgain = true;//will be set to false on the end of the pagination.

		while(fetchAgain) {
			//Get the data (see above)
			JSONObject json = getJSonStringForUrl(url);

			try{
				//Get the element that holds the meta ( JSONArray )
				JSONObject  metaJsonObject = json.getJSONObject("meta");
				String next = metaJsonObject.getString("next");
				if(next==null || next.equals("") || next.equals("null")) {
					fetchAgain = false;
				} else {
					url = JSONURL + next;
				}
				
				
				//Get the element that holds the objects ( JSONArray )
				JSONArray  producteursJsonArray = json.getJSONArray("objects");

				//Loop the Array
				for(int i=0;i < producteursJsonArray.length();i++){						

					JSONObject e = producteursJsonArray.getJSONObject(i);
					int id = e.getInt("id");
					double rating = 0;
					try {
						rating = e.getDouble("rating");
					} catch (JSONException ex) {
						rating = 0;
					}
					Producteur p = new Producteur(
							id, 
							e.getString("nom"), 
							e.getString("adresse"), 
							e.getString("presentation"), 
							rating, 
							e.getString("photo"), 
							e.getString("aoc"), 
							e.getString("commune"), 
							e.getString("resource_uri"));

					producteurList.add(p);
					if(producteurs == null)
						producteurs = new HashMap<Integer, Producteur>();
					producteurs.put(id, p);
				}
			}catch(JSONException e)        {
				Log.e("log_tag", "Error parsing data "+e.toString());
			}
		}
		//Log.d(Constants.TAG, "Nombre de producteurs récupérés : "+producteurList.size());
		return producteurList;
	}

	private static JSONObject getJSonStringForUrl(String url) {

		String result = "";
		JSONObject jArray = null;

		StringBuilder builder = new StringBuilder();
		HttpClient client = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);
		try {
			HttpResponse response = client.execute(httpGet);
			StatusLine statusLine = response.getStatusLine();
			int statusCode = statusLine.getStatusCode();
			if (statusCode == 200) {
				HttpEntity entity = response.getEntity();
				InputStream content = entity.getContent();
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(content));
				String line;
				while ((line = reader.readLine()) != null) {
					builder.append(line);
				}
			} else {
				Log.e(Constants.TAG, "Failed to download file");
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		result = builder.toString();

		//try parse the string to a JSON object
		try{
			jArray = new JSONObject(result);
		}catch(JSONException e){
			Log.e("log_tag", "Error parsing data "+e.toString());
		}

		return jArray;
	}
}
